/*
 * lista.c
 *
 *  Created on: 05/06/2011
 *      Author: joao e sheila
 */

#include "lista.h"


void Cria(LISTA *L) {
    L->comp = 0;
}

TipoElemento Acessa (TipoPosicao p, LISTA *L) {
    if (L->comp > p)
        return L->elementos[p];
    else{
        printf("erro: elemento inexistente \n");
        return 0;}

    return 0;
}

void ImprimeLista (LISTA *L){
    TipoPosicao i = 0;
    for (i = 0; i < L->comp; i++)
        printf("%d ", Acessa(i, L));
    printf("\n");
}

void Insere (TipoElemento x, TipoPosicao p, LISTA *L){
    if (L->comp < MAX){
        TipoPosicao i;
        for(i = (L->comp+1); i > p; i--){
            L->elementos[i] = L->elementos[i-1];
        }
        L->elementos[p] = x;
        L->comp++;
    } else
        printf("erro: lista cheia\n");

}

void Adiciona(TipoElemento x, LISTA *L) {
    Insere(x, L->comp, L);
}

int Vazia (LISTA *L){
    if(L->comp == 0)
        return 1;
    else
        return 0;
}

/* localiza o elemento x na lista e retorna sua posicao */
int Localiza (TipoElemento x, LISTA *L){
    TipoPosicao i;
    for (i = 0; i < L->comp; i++)
        if(L->elementos[i] == x)
            return i;

    return FIM;
}

/* retorna 0 se a lista NAO estiver vazia, FIM caso contrario */
TipoPosicao Primeiro (LISTA *L){
    if (L->comp > 0)
        return 0;
    else
        return FIM;
}

/* retorna FIM se for o ultimo elemento, 0 caso contrario */
TipoPosicao Seguinte (TipoPosicao p, LISTA *L){
    if (L->comp < (p+1)){
        printf("erro: posicao inexistente\n");
    } else if(L->comp == (p+1)){
        return FIM;
    } else {
        return (p+1);
    }
    return 0;
}

/* Retorna uma LISTA C, que é a interseccao da LISTA A com a LISTA B */
void Interseccao(LISTA *A, LISTA *B, LISTA *C){

    TipoPosicao i;
    Cria(C);

    if(!Vazia(A))
        for(i = Primeiro(A); i != FIM; i = Seguinte(i, A))
            if(Localiza(Acessa(i, A), B) != FIM)
                Adiciona(Acessa(i, A), C);

}


/* Retorna uma LISTA C, que é a soma da LISTA A com a LISTA B */
void Soma(LISTA *A, LISTA *B, LISTA *C){

    TipoPosicao i;
    Cria(C);

    if(!Vazia(A))
        for(i = Primeiro(A); i != FIM; i = Seguinte(i, A))
            Adiciona(Acessa(i, A), C);

    if(!Vazia(B))
        for(i = Primeiro(B); i != FIM; i = Seguinte(i, B))
            if (Localiza(Acessa(i, B), C) == FIM)
                Adiciona(Acessa(i,B), C);

}

/* Retorna uma LISTA C, que é a diferença da LISTA A com a LISTA B */
void Diferenca (LISTA *A, LISTA *B, LISTA *C){
    TipoPosicao i;
    Cria(C);

    for(i = Primeiro(A); i != FIM; i = Seguinte(i, A))
        if(Localiza(Acessa(i, A), B) == FIM)
            Adiciona(Acessa(i, A), C);
}

/* Copia o conteudo da lista A para a lista B */
void CopiaLista (LISTA *A, LISTA *B){
     Cria(B);
     int i;
     for(i = Primeiro(A); i != FIM; i = Seguinte(i, A))
        Adiciona(Acessa(i, A), B);
}
